package org.javanum.number;

/**
 * <p>Represents an abstract Group.</p>
 * 
 * <p>A <i>Group</i> is a set {@code S} of elements together with an 
 * operation {@code +} which follows the following four rules:</p>
 *  
 * <p>1. <i>Closure:</i> For any two elements {@code a} and {@code b} in 
 * {@code S}, then {@code a+b} is also in {@code S}</p>
 *   
 * <p>2. <i>Associativity:</i> For any elements {@code a,b} and  {@code c} 
 * in {@code S}, then {@code (a+b)+c=a+(b+c)}</p>
 *    
 * <p>3. <i>Identity:</i> There is an element {@code e} in {@code S} such 
 * that {@code a+e=e+a=a} for any {@code a} in {@code S}</p>
 *     
 * <p>4. <i>Inverse:</i> For any element {@code a} in {@code S}, there is 
 * an element {@code b} in {@code S} such that {@code a+b=b+a=e}, where 
 * {@code e} is the additive identity.</p>
 *     
 * <p>A group is called <i>Abelian</i> if, in addition, the following rule 
 * is satisfied:</p>
 * 
 * <p> for any {@code a} and {@code b} in {@code S}, {@code a+b=b+a}</p>
 * 
 * <p>That is, that the operation is <i>Commutative</i>.A group is 
 * NOT generally required to be Abelian, and implementations of this class 
 * should clearly indicate its commutativity behaviors.</p>
 * 
 * @author Scott Fines
 * Date: Oct 22, 2009
 *
 * @param <T> the group element which can be processed. Since the group 
 * operation need only be applicable to elements inside the group itself, 
 * this type parameter specifies the group construction in a type-safe 
 * manner.
 */
public interface Group<T extends Group<T>> {
	
	/**
	 * <p>Adds {@code summand} to the element {@code this}</p>
	 * 
	 * <p>Note that this method need not be commutative---implementations
	 * should clearly indicate whether or not the group is commutative, or 
	 * if the ordering of this method is important.</p>
	 * 
	 * @param summand the element to be added
	 * @return the result of the computation {@code this+summand}. Note that
	 *  {@code this+summand !=summand+this} <i>necessarily</i>.
	 */
	public T add(T summand);
	
	/**
	 * <p>Subtracts {@code value} from {@code this}</p>
	 * 
	 * <p>In principle, subtraction of the element {@code a} is addition 
	 * of the additive inverse, e.g. {@code a-b=a+(-b)}, where {@code -b} 
	 * is the element such that {@code b+(-b)=-b+b=e} by rule 4. Therefore,
	 * as with addition, order characteristics may be relevant, and this 
	 * method should obey the same commutativity behavior as 
	 * {@link #add(Group)}, and implementations should clearly document 
	 * that behavior. </p>
	 * 
	 * @param value the element to be subtracted
	 * @return the result of the computation {@code this + (-value)}.
	 * Note that {@code this-value!=value-this} <i>necessarily</i>.
	 */
	public T subtract(T value);
	
	/**
	 * <p>Returns the additive identity for this particular group.</p>
	 * 
	 * <p>The additive identity is the element {@code e} such that 
	 * {@code a+e=e+a=a} for any element {@code a} in the group.</p>
	 * 
	 * @return the additive identity for this particular group. This 
	 * identity may also be the additive identity object for a 
	 * particular implementation.
	 */
	public T additiveIdentity();
	
	/**
	 * <p>returns the additive inverse of {@code this}. That is, this 
	 * method returns the value {@code b}, where 
	 * {@code this+b=b+this=additiveIdentity()}
	 * </p>
	 * 
	 * @return the additive inverse of {@code this}.
	 */
	public T additiveInverse();

}
